package com.cmw.core.util;

import com.alibaba.fastjson.JSONObject;
import com.cmw.core.base.exception.ServiceException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 * Web页面工具助手
 *  
 * @author	chengmingwei
 * @date	2015年5月2日 上午9:49:59
 */
public class PageHandler {
	static String staticResourceUri = null;
	
	public static final String DT_NODATAS = "{list:[],totalSize:0,success:true}";
	/**
	 * 当用AJAX请求数据时用户超时输出字符串
	 */
	public static final String SESSION_TIMEOUT_AJAX = "user.session.timeout.break";

	/**
	 * 获取成功返回的JSON数据,成功后返回 msg : 'ok'
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static JSONObject getSuccessJson(){
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", true);
		jsonObject.put("msg", "ok");
		return jsonObject;
	}
	/**
	 * 获取成功返回的JSON数据
	 * @param msg  成功后返回的消息
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static JSONObject getSuccessJson(String msg){
		if(!StringHandler.isValidStr(msg)) msg = "ok";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", true);
		jsonObject.put("msg", msg);
		return jsonObject;
	}

	/**
	 * 获取失败返回的JSON数据,成功后返回 msg : 'no'
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static JSONObject getFailureJson(){
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", false);
		jsonObject.put("msg", "no");
		return jsonObject;
	}

	/**
	 * 获取失败返回的JSON数据
	 * @param msg  失败后返回的消息
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static JSONObject getFailureJson(String msg){
		if(!StringHandler.isValidStr(msg)) msg = "no";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", false);
		jsonObject.put("msg", msg);
		return jsonObject;
	}

	/**
	 * 将List统一包装成JSON数据返回
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static <T> JSONObject getJson(List<T> list){
		return getJson(null, null, list);
	}

	/**
	 * 将List统一包装成JSON数据返回
	 * @param  success 是否成功
	 * @param msg  返回的消息
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static <T> JSONObject getJson(Boolean success, String msg, List<T> list){
		if(null == success) success = true;
		if(!StringHandler.isValidStr(msg)) msg = "ok";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", success);
		jsonObject.put("msg", msg);
		jsonObject.put("datas", list);
		return jsonObject;
	}

	/**
	 * 将一个对象统一包装成JSON数据返回
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static <T> JSONObject getJson(T obj){
		return getJson(null, null, obj);
	}

	/**
	 * 将一个对象统一包装成JSON数据返回
	 * @param  success 是否成功
	 * @param msg  返回的消息
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static <T> JSONObject getJson(Boolean success, String msg, T obj){
		if(null == success) success = true;
		if(!StringHandler.isValidStr(msg)) msg = "ok";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", success);
		jsonObject.put("msg", msg);
		jsonObject.put("datas", obj);
		return jsonObject;
	}

	/**
	 * 将一个Map统一包装成JSON数据返回
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static <T> JSONObject getJson(Map<String,Object> map){
		return getJson(null, null, map);
	}
	/**
	 * 将一个Map统一包装成JSON数据返回
	 * @param  success 是否成功
	 * @param msg  返回的消息
	 * @author chengmingwei
	 * @date 2017-05-22 20:35
	 * @return
	 */
	public static <T> JSONObject getJson(Boolean success, String msg, Map<String,Object> map){
		if(null == success) success = true;
		if(!StringHandler.isValidStr(msg)) msg = "ok";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("success", success);
		jsonObject.put("msg", msg);
		jsonObject.put("datas", map);
		return jsonObject;
	}
		
	/**
	 * 输出静态字符串
	 * @param response
	 * @param str
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJsonString(HttpServletResponse response,String str) {
//		response.setCharacterEncoding("UTF-8");  
		response.setContentType("application/xml;charset=UTF-8");
		response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1/*");
		try {
			PrintWriter out = response.getWriter();
			out.write(str);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @param str
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJson(HttpServletResponse response,boolean success,String str) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", success);
		jsonObj.put("msg", str);
		outJsonString(response, jsonObj.toString());
	}
	
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @param key	key健
	 * @param val	输出JSON 值
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJson(HttpServletResponse response,String key , Object val) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", true);
		jsonObj.put(key, val);
		outJsonString(response, jsonObj.toString());
	}
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @param success 是否成功 [true:成功,false:失败]
	 * @param outJson JSONObject对象
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJson(HttpServletResponse response, boolean success, JSONObject outJson) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", success);
		if(null != outJson) jsonObj.putAll(outJson);
		outJsonString(response, jsonObj.toString());
	}
	
	/**
	 * 输出成功静态字符串
	 * @param response
	 * @param msg 消息串
	 * @author chengmingwei
	 * @date 2016年07月04日 11:56
	 */
	public static void outSuccessJson(HttpServletResponse response,String msg) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", true);
		jsonObj.put("msg", msg);
		outJsonString(response, jsonObj.toString());
	}
	
	/**
	 * 输出失败JSON字符串
	 * @param response
	 * @param msg 失败消息串
	 * @author chengmingwei
	 * @date 2016年07月04日 11:56
	 */
	public static void outFailureJson(HttpServletResponse response,String msg) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", false);
		jsonObj.put("msg", msg);
		outJsonString(response, jsonObj.toString());
	}
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @param success 是否成功 [true:成功,false:失败]
	 * @param msg 消息
	 * @param outJson JSONObject对象
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 * 输出内容：
	 *  {success:true,msg:"ok",jsonData:{id:1,name:"张三"}}
	 */
	public static void outJson(HttpServletResponse response, boolean success, String msg, JSONObject outJson) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", success);
		jsonObj.put("msg", msg);
		if(null != outJson) jsonObj.put("jsonData", outJson);
		outJsonString(response, jsonObj.toString());
	}
	
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJson(HttpServletResponse response,JSONObject outJson) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", true);
		if(null != outJson) jsonObj.putAll(outJson);
		outJsonString(response, jsonObj.toString());
	}
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJson(HttpServletResponse response,Map<String,Object> outMap) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", true);
		jsonObj.putAll(outMap);
		outJsonString(response, jsonObj.toString());
	}
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @param str
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJsonp(HttpServletRequest request,HttpServletResponse response,boolean success,String str) {
		JSONObject jsonObj = new JSONObject();
		jsonObj.put("success", success);
		jsonObj.put("msg", str);
		outJsonp(request, response, jsonObj.toString());
	}
	
	/**
	 * 输出静态字符串
	 * @param response
	 * @param str
	 * @author chengmingwei
	 * @date 2015年5月4日 下午8:52:33
	 */
	public static void outJsonp(HttpServletRequest request,HttpServletResponse response,String str) {
		response.setCharacterEncoding("UTF-8");  
		response.setContentType("application/json");  
		try {
			String callback = request.getParameter("callback");
			if(!StringHandler.isValidStr(callback)) throw new ServiceException("jsonp callback is null !");
			String json = callback+"('"+str+"')";
			PrintWriter out = response.getWriter();
			out.write(json);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}catch (ServiceException e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 获取 Integer 型值
	 * @param colName
	 * @return
	 */
	public static Integer getIVal(HttpServletRequest request, String colName){
		String val = getVal(request, colName);
		return (StringHandler.isValidStr(val)) ? Integer.parseInt(val) : null;
	}
	
	/**
	 * 获取 Long 型值
	 * @param colName
	 * @return
	 */
	public static Long getLVal(HttpServletRequest request, String colName){
		String val = getVal(request, colName);
		return (StringHandler.isValidStr(val)) ? Long.parseLong(val) : null;
	}
	
	/**
	 * 获取 Double 型值
	 * @param colName
	 * @return
	 */
	public static Double getDVal(HttpServletRequest request, String colName){
		String val = getVal(request, colName);
		return (StringHandler.isValidStr(val)) ? Double.parseDouble(val) : null;
	}
	
	/**
	 * 获取 Float 型值
	 * @param colName
	 * @return
	 */
	public static Float getFVal(HttpServletRequest request, String colName){
		String val = getVal(request, colName);
		return (StringHandler.isValidStr(val)) ? Float.parseFloat(val) : null;
	}
	
	/**
	 * 获取 Byte 型值
	 * @param colName
	 * @return
	 */
	public static Byte getBVal(HttpServletRequest request, String colName){
		String val = getVal(request, colName);
		return (StringHandler.isValidStr(val)) ? Byte.parseByte(val) : null;
	}
	
	public static String getVal(HttpServletRequest request, String colName){
		if(null == colName || "".equals(colName)) return "";
		String val = request.getParameter(colName);
		return (null == val) ? "" : val;
	}
	
	/**
	 * 根据指定的参数获取页面中要查询的值，通过 request 去取值
	 * 并以 SHashMap 对象返回
	 * 例如：
	 * 	String args = "name,minunit#I,total#L,amount#F,money#O,date#D";
	 * 如果没有加"#"号则表示是字符串，如果“#” 后有：
	 * 则依次是以下意思：
	 * 		I : Integer	,	L : Long
	 * 		F : Float	,	O : Double
	 * 		D : Date	,	B : Boolean
	 * 	SHashMap params = getQParams(args);
	 * @param args 要从 request 中获取的值 多个以逗号分隔
	 * @return 返回查询参数 SHashMap 对象
	 */
	public static SHashMap<String, Object> getQParams(HttpServletRequest request, String args){
		return getQParams(request, args,null);
	}
	
	/**
	 * 根据指定的参数获取页面中要查询的值，
	 * 并以 SHashMap 对象返回
	 * 例如：
	 * 	String args = "name,minunit#I,total#L,amount#F,money#O,date#D";
	 * 如果没有加"#"号则表示是字符串，如果“#” 后有：
	 * 则依次是以下意思：
	 * 		I : Integer	,	L : Long
	 * 		F : Float	,	O : Double
	 * 		D : Date	,	B : Boolean
	 * 	SHashMap params = getQParams(args);
	 * @param args 要从 request 中获取的值 多个以逗号分隔
	 * @param map 封装页面数据的 map 对象，如果此参数为空，就通过 request 对象直接从请求中取值
	 * @return 返回查询参数 SHashMap 对象
	 */
	public static SHashMap<String, Object> getQParams(HttpServletRequest request, String args, Map<String,String> map){
		SHashMap<String, Object> params = new SHashMap<String, Object>();
		String[] arrStr = StringHandler.Split(",", args);
		String logic = "";
		String key = "";
		Object val=null;
		int len = arrStr.length;
		if(null == map || map.size() == 0){
			for(int i=0; i < len; i++){
				if(arrStr[i] == null) continue;
				//以下为获取页面值，并转型
				String[] fieldArr = parseArgs(arrStr[i],logic);
				key = fieldArr[0];
				if(!StringHandler.isValidStr(key)) continue;
				String keyPrefix = parseKey(key);
				val = request.getParameter(keyPrefix);
				System.out.println(keyPrefix+"="+val);
				if(null == val || "".equals(val) || "undefined".equals(val)) continue;
				put(params,fieldArr,val,logic);
			}
		}else{
			for(int i=0; i < len; i++){
				if(arrStr[i] == null) continue;
				//以下为获取页面值，并转型
				String[] fieldArr = parseArgs(arrStr[i],logic);
				key = fieldArr[0];
				if(!StringHandler.isValidStr(key)) continue;
				String keyPrefix = parseKey(key);
				val = map.get(keyPrefix);
				if(null == val || "".equals(val)) continue;
				put(params,fieldArr,val,logic);
			}
		}
		return params;
	}
	
	/**
	 * 解析字符串KEYS
	 * @param kv 待解析的 key 名称
	 * @param logic 逻辑表达式变量
	 * @return 返回解析后的字符串数组 数组, 第一个为KEY，第二个为 此键将要转换的数据类型
	 */
	public static String[] parseArgs(String kv,String logic){
		int index = kv.indexOf("LOGIC");
		if(-1 != index){
			logic = kv.substring(index);
			kv = kv.substring(0,index);
		}
		//以下为获取页面值，并转型
		return kv.split("#");
	}
	
	/**
	 * 解析 key 值
	 * @param key 
	 * @return 返回解析后的KEY值
	 */
	private static String parseKey(String key){
		return (-1==key.indexOf(".")) ? key : key.substring(key.indexOf(".")+1);
	}

	/**
	 * 往 params 对象中放指定的值
	 * @param params
	 * @param val
	 * @param logic
	 */
	private static void put(SHashMap<String, Object> params, String[] fieldArr, Object val, String logic){
		String filterVal = val.toString();
		filterVal = StringHandler.replaceSqlSign(filterVal);
		if(fieldArr.length>1){	//如果需要转型
			val = StringHandler.getValByType(filterVal,fieldArr[1]);
		}else{
			val = filterVal;
		}
		if(StringHandler.isValidStr(logic)){
			val = filterVal+logic;
		}
		params.put(fieldArr[0], val);
	}
	
	/**
	 * 获取Ip地址
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if(StringHandler.isValidStr(ip) && ip.indexOf(",") != -1){
			ip = ip.split(",")[0].trim();
		}
		return ip;
	}
}
